package com.ease.integration.snmp;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.Null;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class _SnmpUtilTest {
	private Snmp snmp = null;
	private Address targetAddress = null;
	private CommunityTarget target = null;

	public void initComm(String host) throws IOException {
		// 设置Agent方的IP和端口
		targetAddress = GenericAddress.parse("udp:" + host + "/161");
		TransportMapping transport = new DefaultUdpTransportMapping();
		snmp = new Snmp(transport);
		transport.listen();

		target = new CommunityTarget();
		target.setCommunity(new OctetString("public"));
		target.setAddress(targetAddress);
		// 通信不成功时的重试次数
		target.setRetries(2);
		// 超时时间
		target.setTimeout(5000);
		target.setVersion(SnmpConstants.version1);
	}

	public ResponseEvent sendPDU(PDU pdu) throws IOException {
		// 设置 target

		// 向Agent发送PDU，并返回Response
		return snmp.send(pdu, target);
	}

	public void setPDU() throws IOException {
		// set PDU
		PDU pdu = new PDU();
		pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 7, 0 }), new OctetString("8899")));
		pdu.setType(PDU.SET);
		sendPDU(pdu);
	}

	public void getPDU() throws IOException {
		// get PDU
		PDU pdu = new PDU();
		pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 6, 0 })));// pcName
		pdu.setType(PDU.GET);
		readResponse(sendPDU(pdu));
	}

	public void getPDU(String oid) throws IOException {
		// get PDU
		PDU pdu = new PDU();
		pdu.add(new VariableBinding(new OID(oid)));// pcName
		pdu.setType(PDU.GET);
		readResponse(sendPDU(pdu));
	}

	public void readResponse(ResponseEvent respEvnt) {
		// 解析Response
		System.out.println("----------解析Response-------------");
		if (respEvnt != null && respEvnt.getResponse() != null) {
			Vector<VariableBinding> recVBs = (Vector<VariableBinding>) respEvnt.getResponse().getVariableBindings();
			for (int i = 0; i < recVBs.size(); i++) {
				VariableBinding recVB = recVBs.elementAt(i);
				System.out.println(recVB.getOid() + " : " + recVB.getVariable());
			}
		} else {
			System.out.println("respEvnt is  null");
		}

	}

	public Map<String, String> doWalk(String root) throws IOException {
		PDU response;
		PDU request = new PDU();
		request.setType(PDU.GETNEXT);
		request.add(new VariableBinding(new OID(root)));
		Map<String, String> resultList = new HashMap<String, String>();
		OID rootOID = request.get(0).getOid();
		do {
			ResponseEvent responseEvent = snmp.send(request, target);
			response = responseEvent.getResponse();
		} while (!processWalk(response, request, rootOID, resultList));
		return resultList;
	}

	private boolean processWalk(PDU response, PDU request, OID rootOID, Map<String, String> list) {

		if ((response == null) || (response.getErrorStatus() != 0) || (response.getType() == PDU.REPORT)) {
			return true;
		}
		boolean finished = false;
		OID lastOID = request.get(0).getOid();
		for (int i = 0; (!finished) && (i < response.size()); i++) {
			VariableBinding vb = response.get(i);
			if ((vb.getOid() == null) || (vb.getOid().size() < rootOID.size()) || (rootOID.leftMostCompare(rootOID.size(), vb.getOid()) != 0)) {
				finished = true;
			} else if (Null.isExceptionSyntax(vb.getVariable().getSyntax())) {
				finished = true;
			} else if (vb.getOid().compareTo(lastOID) <= 0) {
				finished = true;
			} else {
				lastOID = vb.getOid();
				list.put(vb.toString().split("=")[0], vb.toString().split("=")[1].trim());
				System.out.println(vb.toString());
			}
		}

		if (response.size() == 0) {
			finished = true;
		}
		if (!finished) {
			VariableBinding next = response.get(response.size() - 1);
			next.setVariable(new Null());
			request.set(0, next);
			request.setRequestID(new Integer32(0));
		}
		return finished;
	}

	public void release() {
		try {
			snmp.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		System.out.println("----------start-------------");
		_SnmpUtilTest util = null;
		try {
			util = new _SnmpUtilTest();
			// util.initComm("192.168.239.3");//HW S9303
			util.initComm("192.168.239.5");// HW MA5680T

			// util.initComm("192.168.239.130");//ZTE S8902
			// util.setPDU();
			// util.getPDU();
			// util.doWalk("1.3.6.1.2.1.1");//HW
			util.getPDU("1.3.6.1.2.1.1.1.0");// HW
			// util.getPDU("1.3.6.1.4.1.3902.3.348.2.1.1.1");//ZTE
		} catch (IOException e) {
			Throwable throwable = ExceptionUtils.getRootCause(e);
			System.out.println(throwable.getMessage());
			e.printStackTrace();

		} finally {
			util.release();
		}

	}

	// targetAddress = GenericAddress.parse("udp:192.168.239.3/161");
	// ----------start-------------
	// ----------解析Response-------------
	// 1.3.6.1.2.1.1.6.0 : Shenzhen China
	// 1.3.6.1.2.1.1.1.0 = Huawei Integrated Access Software
	// 1.3.6.1.2.1.1.2.0 = 1.3.6.1.4.1.2011.2.115
	// 1.3.6.1.2.1.1.3.0 = 37 days, 23:24:13.40
	// 1.3.6.1.2.1.1.4.0 = R&D Shenzhen, Huawei Technologies Co., Ltd.
	// 1.3.6.1.2.1.1.5.0 = MA5680-Peixunjidi
	// 1.3.6.1.2.1.1.6.0 = Shenzhen China
	// 1.3.6.1.2.1.1.7.0 = 78

}